home *** CD-ROM | disk | FTP | other *** search
/ Ian & Stuart's Australian Mac 1993 September / September 93.iso / Archives / Utilities / Quicktime / E D T V / EDTV.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-05  |  19.9 KB  |  827 lines  |  [TEXT/KAHL]

  1. /****************************************************************************/
  2. /*                                                                            */
  3. /*    Application:    E D T V                                                    */
  4. /*                                                                            */
  5. /*    Description:    This file contains all the routines for loading,        */
  6. /*                    displaying, and disposing movies in a window.            */
  7. /*                                                                            */
  8. /*    File:            EDTV.c                                                    */
  9. /*                                                                            */
  10. /*    Files:            about.c        - routines for the about box                */
  11. /*                    EDTV.c        - routines for displaying movies            */
  12. /*                    menu.c        - routines for handling the menu            */
  13. /*                    remote.c    - routines for controlling the movie        */
  14. /*                    EDTV.h        - header file information                    */
  15. /*                                                                            */
  16. /*    Programmer:        Edgar Lee                                                */
  17. /*    Organization:    Apple Computer, Inc.                                    */
  18. /*    Department:        Developer Technical Support, DTS                        */
  19. /*    Language:        C (Think C version 5.0)                                    */
  20. /*    Date Created:    10-26-91                                                */
  21. /*                                                                            */
  22. /****************************************************************************/
  23.  
  24. #include "EDTV.h"
  25.  
  26. #define    BORDER            100            /* Distance from the tv's rim to the window (in pixels). */
  27.  
  28. #define    DEFAULTWIDTH    300            /* Default width of the window. */
  29. #define    DEFAULTHEIGHT    300            /* Default height of the window. */
  30.  
  31. WindowPtr        gWindow;            /* Window used for displaying the movie. */
  32. Movie            gMovie1;            /* Movie stored in movie file. */
  33. Movie            gMovie2;            /* Copy of movie #1. */
  34. GWorldPtr        gGWorld;            /* Gworld used to store the offscreen image of the tv. */
  35. PixMapHandle    gPixMap;            /* Handle to gworld's pixmap. */
  36. RgnHandle        gOrigMovieClipRgn;    /* Region defining the movie's original clip region. */
  37.  
  38. TimeValue        gMovieDuration;        /* Total runtime of movie. */
  39.  
  40. Rect            gMovie1Rect;        /* Bounding rect used for movie #1. */
  41.  
  42. int                gTVWidth;            /* Width of tv pict. */
  43. int                gTVHeight;            /* Height of tv pict. */
  44. int                gTVRimW;            /* Width of tv's rim. */
  45. int                gTVRimH;            /* Height of tv's rim. */
  46.  
  47. int                gMoviesStatus;        /* Contains current status of player:    */
  48.                                     /*    NO_MOVIE, MOVIE_LOADED, HIDDEN_MOVIE.    */
  49.  
  50. /*-------------------------------------------------------------------------------------*/
  51.  
  52. main()
  53. {
  54.     initMac();                /* Do the standard mac initialization. */
  55.     
  56.     checkSysEnviron();        /* Check if movie toolbox is installed. */
  57.     
  58.     EnterMovies();            /* Initialize the movie toolbox. */
  59.     setUpMenus();            /* Create the menus. */
  60.     
  61.     initOffscreenTV();        /* Create the offscreen gworld containing the tv image. */
  62.     initParameters();        /* Initialize the parameters used throughout the program. */
  63.     
  64.     createWindow();            /* Create the window used for the movie. */
  65.     createRWindow();        /* Create the window used for the remote control. */
  66.     
  67.     doEventLoop();            /* Handle all incoming events. */
  68. }
  69.  
  70. /*-------------------------------------------------------------------------------------*/
  71.  
  72. void initMac()
  73. {
  74.     InitGraf( &thePort );
  75.     InitFonts();
  76.     InitWindows();
  77.     InitMenus();
  78.     TEInit();
  79.     InitDialogs( nil );
  80.     InitCursor();
  81.     FlushEvents( 0, everyEvent );
  82. }
  83.  
  84. /*-------------------------------------------------------------------------------------*/
  85.  
  86. void checkSysEnviron()
  87. {
  88.     long    version;
  89.     
  90.     /* Even though QuickTime runs under system 6, EDTV requires system 7 since    */
  91.     /*    some of the quickdraw routines it uses are only available under 7.0.    */
  92.         
  93.     Gestalt( gestaltSystemVersion, &version );
  94.     
  95.     if (version < 0x0700)
  96.     {
  97.         ParamText( "\pSorry, this application only runs under system 7.  Please try again.",
  98.                         "\p", "\p", "\p" );
  99.         Alert( 128, nil );
  100.         ExitToShell();
  101.     }
  102.     
  103.     if (Gestalt( gestaltQuickTime, &version ) != noErr)
  104.     {
  105.         ParamText( "\pQuickTime not installed.  Please try again.", "\p", "\p", "\p" );
  106.         Alert( 128, nil );
  107.         ExitToShell();
  108.     }
  109. }
  110.  
  111. /*-------------------------------------------------------------------------------------*/
  112.  
  113. void initOffscreenTV()
  114. {
  115.     Rect            rect;            /* Temporary rect used for the pict & gworld. */ 
  116.     PicHandle        pict;            /* Handle to the tv pict stored in resource fork. */
  117.     CGrafPtr        currentPort;    /* Port used before switching to the gworld's. */
  118.     GDHandle        currentDevice;    /* GDevice used before switching to the gworld's. */
  119.     DialogPtr        dialog;            /* Dialog displaying 'please wait' message. */
  120.  
  121.     dialog = GetNewDialog( 128, 0L, (WindowPtr)-1L );
  122.     UpdtDialog( dialog, dialog->visRgn );
  123.             
  124.     pict = (PicHandle)GetResource( 'PICT', 129 );
  125.  
  126.     rect = (**pict).picFrame;
  127.     
  128.     gTVWidth = rect.right - rect.left;
  129.     gTVHeight = rect.bottom - rect.top;
  130.     
  131.     NewGWorld( &gGWorld, 8, &rect, GetCTable( 8 + 32 ), nil, 0 );
  132.     gPixMap = GetGWorldPixMap( gGWorld );
  133.     LockPixels( gPixMap );
  134.     
  135.     GetGWorld( ¤tPort, ¤tDevice );
  136.     SetGWorld( gGWorld, nil );
  137.     
  138.     EraseRect( &rect );
  139.     DrawPicture( pict, &rect );
  140.     
  141.     SetGWorld( currentPort, currentDevice );
  142.     
  143.     KillPicture( pict );
  144.     DisposDialog( dialog );
  145. }
  146.  
  147. /*-------------------------------------------------------------------------------------*/
  148.  
  149. void initParameters()
  150. {
  151.     gMoviesStatus = NO_MOVIE;
  152.     
  153.     SetRect( &gMovie1Rect, (DEFAULTWIDTH - gTVWidth) / 2,
  154.                     (DEFAULTHEIGHT - gTVHeight) / 2,
  155.                     (DEFAULTWIDTH - gTVWidth) / 2 + gTVWidth,
  156.                     (DEFAULTHEIGHT - gTVHeight) / 2 + gTVHeight );
  157. }
  158.  
  159. /*-------------------------------------------------------------------------------------*/
  160.  
  161. void createWindow()
  162. {
  163.     Rect    rect;
  164.     
  165.     SetRect( &rect, RLEFT + RWIDTH + 10, RTOP,
  166.                     RLEFT + RWIDTH + 10 + DEFAULTWIDTH, RTOP + DEFAULTHEIGHT );
  167.     
  168.     gWindow = NewCWindow( 0L, &rect, "\pE D T V", true, noGrowDocProc,
  169.                             (WindowPtr)-1L, true, 0L );
  170.                             
  171.     SetPort( gWindow );
  172. }
  173.  
  174. /*-------------------------------------------------------------------------------------*/
  175.  
  176. void selectMovie()
  177. {
  178.     SFTypeList            typeList;
  179.     StandardFileReply    reply;
  180.     short                resRefNum;
  181.     short                resId = 0;
  182.     Str255                resName;
  183.     OSErr                error;
  184.     
  185.     typeList[0] = 'MooV';
  186.     
  187.     HideWindow( gWindow );
  188.     StandardGetFilePreview( nil, 1, typeList, &reply );
  189.     
  190.     if (reply.sfGood)
  191.     {
  192.         ClearMoviesStickyError();
  193.         
  194.         error = OpenMovieFile( &reply.sfFile, &resRefNum, fsRdPerm );
  195.         error = NewMovieFromFile( &gMovie1, resRefNum, &resId, resName, newMovieActive, nil );
  196.         error = NewMovieFromFile( &gMovie2, resRefNum, &resId, resName, newMovieActive, nil );
  197.         error = CloseMovieFile( resRefNum );
  198.         
  199.         if (gMovie1 == nil || gMovie2 == nil || error)
  200.             return;
  201.  
  202.         SetMovieGWorld( gMovie1, (CGrafPtr)gWindow, nil );
  203.         SetMovieGWorld( gMovie2, (CGrafPtr)gWindow, nil );
  204.  
  205.         gOrigMovieClipRgn = GetMovieClipRgn( gMovie1 );
  206.         
  207.         SetMovieActive( gMovie1, false );
  208.         SetMovieActive( gMovie2, false );
  209.         
  210.         GetMovieBox( gMovie1, &gMovie1Rect );
  211.         
  212.         gMovieDuration = GetMovieDuration( gMovie1 );
  213.         
  214.         gMoviesStatus = MOVIE_LOADED;
  215.         setupDisplay();
  216.                 
  217.         SetWTitle( gWindow, reply.sfFile.name );
  218.         ShowWindow( gWindow );
  219.     }
  220. }
  221.  
  222. /*-------------------------------------------------------------------------------------*/
  223.  
  224. void closeMovie()
  225. {
  226.     gMoviesStatus = NO_MOVIE;
  227.  
  228.     redrawRemoteOnClose();
  229.     
  230.     SetPort( gWindow );
  231.     HideWindow( gWindow );
  232.                         
  233.     DisposeMovie( gMovie1 );
  234.     DisposeMovie( gMovie2 );
  235.  
  236.     initParameters();
  237.     SizeWindow( gWindow, DEFAULTWIDTH, DEFAULTHEIGHT, true );
  238.     updateGWorld();
  239. }
  240.  
  241. /*-------------------------------------------------------------------------------------*/
  242.  
  243. void setupDisplay()
  244. {
  245.     resizeWindow();
  246.     positionMovie();
  247.     updateGWorld();
  248.     drawVolume();
  249.     drawPoster();
  250. }
  251.  
  252. /*-------------------------------------------------------------------------------------*/
  253.  
  254. void resizeWindow()
  255. {
  256.     int        width, height;
  257.     
  258.     gTVRimW = 60.0 * ((float)(gMovie1Rect.right - gMovie1Rect.left) / (float)gTVWidth);
  259.     gTVRimH = 60.0 * ((float)(gMovie1Rect.bottom - gMovie1Rect.top) / (float)gTVHeight);
  260.     
  261.     width = gMovie1Rect.right - gMovie1Rect.left + gTVRimW + BORDER;
  262.     height = gMovie1Rect.bottom - gMovie1Rect.top + gTVRimH + BORDER;
  263.     
  264.     SizeWindow( gWindow, width, height, true );
  265. }
  266.  
  267. /*-------------------------------------------------------------------------------------*/
  268.  
  269. void positionMovie()
  270. {
  271.     int        width, height;
  272.     
  273.     width = gWindow->portRect.right - gWindow->portRect.left;
  274.     height = gWindow->portRect.bottom - gWindow->portRect.top;
  275.     
  276.     OffsetRect( &gMovie1Rect, -gMovie1Rect.left, -gMovie1Rect.top);
  277.     OffsetRect( &gMovie1Rect, (width - (gMovie1Rect.right - gMovie1Rect.left)) / 2,
  278.                         (height - (gMovie1Rect.bottom - gMovie1Rect.top)) * 0.45 );
  279.  
  280.     SetMovieBox( gMovie1, &gMovie1Rect );
  281. }
  282.  
  283. /*-------------------------------------------------------------------------------------*/
  284.  
  285. void updateGWorld()
  286. {
  287.     Rect        rect;
  288.     CGrafPtr    currentPort;        /* Port used before switching to the gworld. */
  289.     GDHandle    currentDevice;        /* GDevive used before switching to the gworld. */
  290.  
  291.     rect = gMovie1Rect;
  292.     InsetRect( &rect, -gTVRimW, -gTVRimH );
  293.     
  294.     GetGWorld( ¤tPort, ¤tDevice );
  295.     
  296.     SetGWorld( gGWorld, nil );
  297.     
  298.     UpdateGWorld( &gGWorld, 8, &rect, GetCTable( 8 + 32 ), nil, stretchPix );
  299.     gPixMap = GetGWorldPixMap( gGWorld );
  300.     LockPixels( gPixMap );
  301.     
  302.     SetGWorld( currentPort, currentDevice );
  303. }
  304.  
  305. /*-------------------------------------------------------------------------------------*/
  306.  
  307. void setGridClipRgn( divisions )
  308. int    divisions;
  309. {
  310.     int            i, j;
  311.     int            width, height;
  312.     RgnHandle    rgn;
  313.     Rect        rectRgn;
  314.  
  315.     SetPort( gWindow );
  316.     
  317.     StopMovie( gMovie2 );
  318.     SetMovieActive( gMovie2, false );
  319.  
  320.     useColor( BLACK, FG );
  321.     PaintRect( &gMovie1Rect );
  322.  
  323.     width = (gMovie1Rect.right - gMovie1Rect.left) / divisions + 1;
  324.     height = (gMovie1Rect.bottom - gMovie1Rect.top) / divisions + 1;
  325.     
  326.     rgn = NewRgn();
  327.     
  328.     if (divisions == 1)
  329.         rgn = gOrigMovieClipRgn;
  330.     else
  331.     {
  332.         rgn = NewRgn();
  333.     
  334.         OpenRgn();
  335.     
  336.         for (j = 0; j < divisions; j++)
  337.         {
  338.             for ( i = 0; i < divisions; i++)
  339.             {
  340.                 rectRgn.left = width * i + 1;
  341.                 rectRgn.top = height * j + 1;
  342.                 rectRgn.right = width * i + width;
  343.                 rectRgn.bottom = height * j + height;
  344.                 
  345.                 FrameRect( &rectRgn );
  346.             }
  347.         }
  348.         
  349.         CloseRgn( rgn );
  350.     }
  351.     
  352.     SetMovieClipRgn( gMovie1, rgn );
  353.     SetMovieBox( gMovie1, &gMovie1Rect );
  354.     
  355.     DisposeRgn( rgn );
  356. }
  357.  
  358. /*-------------------------------------------------------------------------------------*/
  359.  
  360. void setPiPClipRgn( pos )
  361. int    pos;
  362. {
  363.     int            width, height;
  364.     Rect        rect;
  365.     Rect        pipRect;
  366.     RgnHandle    rgn;
  367.     
  368.     SetPort( gWindow );
  369.     
  370.     SetMovieActive( gMovie2, false );
  371.     
  372.     rect = gMovie1Rect;
  373.     OffsetRect( &rect, -rect.left, -rect.top );
  374.  
  375.     width = rect.right - rect.left;
  376.     height = rect.bottom - rect.top;
  377.     
  378.     pipRect = rect;
  379.  
  380.     InsetRect( &pipRect, width / 4,  height / 4 );
  381.     
  382.     if (pos == LRSPOT)
  383.         OffsetRect( &pipRect, width / 5, height / 5 );
  384.     else if (pos == URSPOT)
  385.         OffsetRect( &pipRect, width / 5, -height / 5 );
  386.     else if (pos == ULSPOT)
  387.         OffsetRect( &pipRect, -width / 5, -height / 5 );
  388.     else if (pos == LLSPOT)
  389.         OffsetRect( &pipRect, -width / 5, height / 5 );
  390.         
  391.     rgn = NewRgn();
  392.     OpenRgn();
  393.     
  394.     FrameRect( &rect );
  395.     FrameRect( &pipRect );
  396.     
  397.     CloseRgn( rgn );
  398.     
  399.     SetMovieClipRgn( gMovie1, rgn );
  400.     SetMovieBox( gMovie1, &gMovie1Rect );
  401.         
  402.     rect = pipRect;
  403.     OffsetRect( &rect, -rect.left, -rect.top );
  404.     OffsetRect( &rect, gMovie1Rect.left + pipRect.left, gMovie1Rect.top + pipRect.top );
  405.     
  406.     SetMovieBox( gMovie2, &rect );
  407.     SetMovieClipRgn( gMovie2, gOrigMovieClipRgn );
  408.     
  409.     if (!GetMovieActive( gMovie2 ))
  410.         SetMovieActive( gMovie2, true );
  411.             
  412.     DisposeRgn( rgn );
  413. }
  414.  
  415. /*-------------------------------------------------------------------------------------*/
  416.  
  417. void setSplitClipRgn( pos )
  418. int pos;
  419. {
  420.     int            width, height;
  421.     Rect        rect;
  422.     Rect        pipRect;
  423.     RgnHandle    rgn;
  424.     
  425.     SetPort( gWindow );
  426.  
  427.     rect = gMovie1Rect;
  428.     OffsetRect( &rect, -rect.left, -rect.top );
  429.  
  430.     width = rect.right - rect.left;
  431.     height = rect.bottom - rect.top;
  432.     
  433.     pipRect = rect;
  434.     
  435.     if (pos == RSPLIT)
  436.     {
  437.         pipRect.left = pipRect.left + (pipRect.right - pipRect.left) / 2;
  438.         rect.right = rect.right - (rect.right - rect.left) / 2;
  439.     }
  440.     else if (pos == LSPLIT)
  441.     {
  442.         pipRect.right = pipRect.right - (pipRect.right - pipRect.left) / 2;
  443.         rect.left = rect.left + (rect.right - rect.left) / 2;
  444.     }
  445.     else if (pos == TSPLIT)
  446.     {
  447.         pipRect.top = pipRect.top + (pipRect.bottom - pipRect.top) / 2;
  448.         rect.bottom = rect.bottom - (rect.bottom - rect.top) / 2;
  449.     }
  450.     else if (pos == BSPLIT)
  451.     {
  452.         pipRect.bottom = pipRect.bottom - (pipRect.bottom - pipRect.top) / 2;
  453.         rect.top = rect.top + (rect.bottom - rect.top) / 2;
  454.     }
  455.         
  456.     rgn = NewRgn();
  457.     OpenRgn();
  458.     
  459.     FrameRect( &rect );
  460.     FrameRect( &pipRect );
  461.     
  462.     CloseRgn( rgn );
  463.     
  464.     SetMovieClipRgn( gMovie1, rgn );
  465.     OffsetRect( &rect, gMovie1Rect.left, gMovie1Rect.top );
  466.     SetMovieBox( gMovie1, &rect );
  467.         
  468.     rect = pipRect;
  469.     OffsetRect( &rect, -rect.left, -rect.top );
  470.     OffsetRect( &rect, gMovie1Rect.left + pipRect.left, gMovie1Rect.top + pipRect.top );
  471.     
  472.     SetMovieBox( gMovie2, &rect );
  473.     SetMovieClipRgn( gMovie2, gOrigMovieClipRgn );
  474.     
  475.     if (!GetMovieActive( gMovie2 ))
  476.         SetMovieActive( gMovie2, true );
  477.  
  478.     DisposeRgn( rgn );
  479. }
  480.  
  481. /*-------------------------------------------------------------------------------------*/
  482.  
  483. void setStillFrames()
  484. {
  485.     int                i, j;
  486.     int                divisions = 3;
  487.     int                width, height;
  488.     Rect            rect;
  489.     TimeRecord        tr;
  490.     TimeValue        timeValue;
  491.     PicHandle        pict;
  492.     RgnHandle        rgn;
  493.     
  494.     if (divisions == 1)
  495.         
  496.     SetPort( gWindow );
  497.     
  498.     StopMovie( gMovie1 );
  499.     StopMovie( gMovie2 );
  500.     
  501.     setGridClipRgn( 1 );
  502.  
  503.     SetMovieActive( gMovie1, false );
  504.     SetMovieActive( gMovie2, false );
  505.  
  506.     width = (gMovie1Rect.right - gMovie1Rect.left) / divisions;
  507.     height = (gMovie1Rect.bottom - gMovie1Rect.top) / divisions;
  508.  
  509.     useColor( BLACK, FG );
  510.     PaintRect( &gMovie1Rect );
  511.  
  512.     timeValue = GetMovieTime( gMovie1, &tr );
  513.     
  514.     for (j = 0; j < divisions; j++)
  515.     {
  516.         for ( i = 0; i < divisions; i++)
  517.         {
  518.             timeValue += tr.scale;        
  519.             
  520.             if (timeValue > gMovieDuration)
  521.                 timeValue = 0;
  522.             
  523.             SetRect( &rect, gMovie1Rect.left + width * i,
  524.                             gMovie1Rect.top + height * j,
  525.                             gMovie1Rect.left + width * i + width,
  526.                             gMovie1Rect.top + height * j + height );
  527.     
  528.             pict = GetMoviePict( gMovie1, timeValue );
  529.             DrawPicture( pict, &rect );
  530.             KillPicture( pict );
  531.         }
  532.     }
  533. }
  534.  
  535. /*-------------------------------------------------------------------------------------*/
  536.  
  537. void drawWindowAndMovie()
  538. {
  539.     Rect            rect;
  540.     BitMap            TVMask;
  541.     
  542.     SetPort( gWindow );
  543.     
  544.     useColor( BLACK, FG );
  545.     useColor( WHITE, BG );
  546.     
  547.     PaintRect( &gWindow->portRect );
  548.         
  549.     rect = gMovie1Rect;
  550.     InsetRect( &rect, -gTVRimW, -gTVRimH );
  551.  
  552.     createTVMask( &rect, &TVMask );
  553.     CopyDeepMask( (BitMap*)*gPixMap, &TVMask, &gWindow->portBits,
  554.                 &(**gPixMap).bounds, &rect, &rect,ditherCopy, 0 );
  555.     
  556.     DisposePtr( TVMask.baseAddr );
  557.     
  558.     if (gMoviesStatus == MOVIE_HIDDEN)
  559.         setStillFrames();
  560.     
  561.     if (gMoviesStatus == MOVIE_LOADED)
  562.         SetMovieActive( gMovie1, true );
  563. }
  564.  
  565. /*-------------------------------------------------------------------------------------*/
  566.  
  567. void drawWindowOnly()
  568. {
  569.     Rect        rect;
  570.     PicHandle    pict;
  571.     
  572.     SetPort( gWindow );
  573.     
  574.     pict = (PicHandle)GetResource( 'PICT', 128 );
  575.     HPurge( pict );
  576.     DrawPicture( pict, &gWindow->portRect );
  577. }
  578.  
  579. /*-------------------------------------------------------------------------------------*/
  580.  
  581. void createTVMask( rect, TVMask )
  582. Rect *rect;
  583. BitMap *TVMask;
  584. {
  585.     long            count;
  586.     RGBColor        white = { 0xffff, 0xffff, 0xffff };
  587.     pascal Boolean    matchProc();
  588.  
  589.     TVMask->bounds = *rect;
  590.     TVMask->rowBytes =  (TVMask->bounds.right - TVMask->bounds.left + 15) / 16 * 2;
  591.     count = TVMask->rowBytes * (TVMask->bounds.bottom - TVMask->bounds.top);
  592.     TVMask->baseAddr = NewPtrClear( count );
  593.         
  594.     CalcCMask( (BitMap*)*gPixMap, TVMask, &(**gPixMap).bounds,
  595.                 rect, &white, matchProc, 0 );
  596. }
  597.  
  598. /*-------------------------------------------------------------------------------------*/
  599.  
  600. static pascal Boolean matchProc( color, position )
  601. RGBColor    *color;
  602. long        *position;
  603. {
  604.     GDHandle    currDevice;        /* Handle to the current GDevice. */
  605.     MatchRec    *matchInfo;        /* Pointer to the GDevice’s MatchRec record. */
  606.  
  607.     currDevice = GetGDevice();
  608.     matchInfo = (MatchRec *)(**currDevice).gdRefCon;
  609.  
  610.     if (matchInfo->red == color->red && matchInfo->green == color->green &&
  611.         matchInfo->blue == color->blue)
  612.         *position = 0;
  613.     else
  614.         *position = 1;
  615.         
  616.     return true;
  617. }
  618.  
  619. /*-------------------------------------------------------------------------------------*/
  620.  
  621. void useColor( index, which )
  622. int    index;
  623. int    which;
  624. {
  625.     RGBColor    color;
  626.     
  627.     if (index == WHITE)
  628.         color.red = color.green = color.blue = 0xffff;
  629.     else if (index == BLACK)
  630.         color.red = color.green = color.blue = 0;
  631.     else if (index == SLATE)
  632.         color.red = color.green = color.blue = 8738;
  633.     else if (index == RED)
  634.     {
  635.         color.red = 0xffff;
  636.         color.green = color.blue = 0;
  637.     }
  638.     else if (index == MUSTARD)
  639.     {
  640.         color.red = color.green = 65535;
  641.         color.blue = 39321;
  642.     }
  643.     else if (index == GREY)
  644.         color.red = color.green = color.blue = 0x4fff;
  645.     else if (index == BLUE)
  646.     {
  647.         color.red = color.green = 0;
  648.         color.blue = 0xffff;
  649.     }
  650.     
  651.     if (which == BG)
  652.         RGBBackColor( &color );
  653.     else
  654.         RGBForeColor( &color );    
  655. }
  656.  
  657. /*-------------------------------------------------------------------------------------*/
  658.  
  659. void doEventLoop()
  660. {
  661.     EventRecord            anEvent;
  662.     WindowPtr            evtWind;
  663.     short                  clickArea;
  664.     Rect                 screenRect;
  665.     Boolean                ret;
  666.     Point                point;
  667.     long                tick;
  668.     long                movies1Value, movies2Value;
  669.     static TimeValue    oMovies1Value = 0, oMovies2Value = 0;
  670.     static long            otick = 0;
  671.     extern WindowPtr    gRWindow;
  672.     extern int            gLoopSetting;
  673.     
  674.     for (;;)
  675.     {
  676.         ret = WaitNextEvent( everyEvent, &anEvent, 0, nil );
  677.         
  678.         if (gMoviesStatus == MOVIE_LOADED)
  679.         {
  680.             if (IsMovieDone( gMovie1 ) && GetMovieRate( gMovie1 ) > 0)
  681.             {
  682.                 if (gLoopSetting == CONTINUOUS_PLAY)
  683.                     GoToBeginningOfMovie( gMovie1 );
  684.                 else
  685.                     StopMovie( gMovie1 );
  686.             }
  687.             else if (GetMovieTime( gMovie1, nil ) == 0 && GetMovieRate( gMovie1 ) < 0)
  688.             {
  689.                 if (gLoopSetting == CONTINUOUS_PLAY)
  690.                     GoToEndOfMovie( gMovie1 );
  691.                 else
  692.                     StopMovie( gMovie1 );
  693.             }
  694.                     
  695.             MoviesTask( gMovie1, (long)0 );
  696.             
  697.             if (GetMovieActive( gMovie2 ))
  698.             {
  699.                 if (IsMovieDone( gMovie2 ) && GetMovieRate( gMovie2 ) > 0)
  700.                 {
  701.                     if (gLoopSetting == CONTINUOUS_PLAY)
  702.                         GoToBeginningOfMovie( gMovie2 );
  703.                     else
  704.                         StopMovie( gMovie2 );
  705.                 }
  706.                 else if (GetMovieTime( gMovie2, nil ) == 0 && GetMovieRate( gMovie2 ) < 0)
  707.                 {
  708.                     if (gLoopSetting == CONTINUOUS_PLAY)
  709.                         GoToEndOfMovie( gMovie2 );
  710.                     else
  711.                         StopMovie( gMovie2 );
  712.                 }
  713.                 
  714.                 MoviesTask( gMovie2, (long)0 );
  715.             }
  716.             
  717.             if (((tick = TickCount()) - otick) >= 15)
  718.             {
  719.                 movies1Value = GetMovieTime( gMovie1, nil );
  720.                 movies2Value = GetMovieTime( gMovie2, nil );
  721.                 
  722.                 if ((movies1Value != oMovies1Value) || (movies2Value != oMovies2Value))
  723.                 {
  724.                     drawCurrentTime();
  725.                     oMovies1Value = movies1Value;
  726.                     oMovies2Value = movies2Value;
  727.                 }
  728.                 otick = tick;
  729.             }
  730.         }
  731.         
  732.         if (ret)
  733.         {
  734.             if (anEvent.what == mouseDown)
  735.             {
  736.                 clickArea = FindWindow( anEvent.where, &evtWind );
  737.                 
  738.                 if (clickArea == inDrag)
  739.                 {
  740.                     screenRect = (**GetGrayRgn ()).rgnBBox;
  741.                     DragWindow( evtWind, anEvent.where, &screenRect );
  742.                 }
  743.                 else if (clickArea == inMenuBar)
  744.                 {
  745.                     adjustMenus();
  746.                     handleMenu( MenuSelect( anEvent.where ) );
  747.                 }
  748.                 else if (clickArea == inContent)
  749.                 {
  750.                     if (evtWind != FrontWindow())
  751.                         SelectWindow( evtWind );
  752.                     
  753.                     if (evtWind == gRWindow)
  754.                     {
  755.                         SetPort( gRWindow );
  756.                         
  757.                         point = anEvent.where;
  758.                         GlobalToLocal( &point );
  759.                         
  760.                         doRemoteEvent( point );
  761.                     }
  762.                 }
  763.                 else if (clickArea == inGoAway)
  764.                     if (TrackGoAway( evtWind, anEvent.where ))
  765.                     {
  766.                         if (gMoviesStatus == MOVIE_LOADED)
  767.                             closeMovie();
  768.                         else
  769.                             HideWindow( gWindow );
  770.                     }
  771.             }
  772.             else if (anEvent.what == updateEvt)
  773.             {
  774.                 evtWind = (WindowPtr)anEvent.message;    
  775.                 SetPort( evtWind );
  776.                 
  777.                 BeginUpdate( evtWind );
  778.             
  779.                 if (evtWind == gWindow)
  780.                 {
  781.                     if (gMoviesStatus == NO_MOVIE)
  782.                         drawWindowOnly();
  783.                     else
  784.                     {
  785.                         UpdateMovie( gMovie1 );
  786.                         
  787.                         if (GetMovieActive( gMovie2 ))
  788.                             UpdateMovie( gMovie2 );
  789.                             
  790.                         drawWindowAndMovie();
  791.                         
  792.                         MoviesTask( gMovie1, (long)0 );
  793.                         MoviesTask( gMovie2, (long)0 );
  794.                     }
  795.                         
  796.                 }
  797.                 else if (evtWind == gRWindow)
  798.                     drawRemote();
  799.                     
  800.                 EndUpdate (evtWind);
  801.             }
  802.             else if (anEvent.what ==  keyDown || anEvent.what == autoKey)
  803.             {
  804.                 if ((anEvent.modifiers & cmdKey) != 0)
  805.                 {
  806.                     adjustMenus();
  807.                     handleMenu( MenuKey( (char)(anEvent.message & charCodeMask) ) );
  808.                 }
  809.             }
  810.         }
  811.     }
  812. }
  813.  
  814. /*-------------------------------------------------------------------------------------*/
  815.  
  816. void quit()
  817. {
  818.     if (gMoviesStatus == MOVIE_LOADED)
  819.     {
  820.         DisposeMovie( gMovie1 );
  821.         DisposeMovie( gMovie2 );
  822.     }
  823.     
  824.     ExitMovies();
  825.     ExitToShell();
  826. }
  827.